package monopd;

import java.io.File;
import java.io.IOException;

// This class is intended to be used with the JAtlantik 
// local copy of Monopd
public class Monopd implements Runnable
{
	// contains a Process, ProcessBuilder
	private ProcessBuilder builder;
	private volatile Process process;
	
	// monopd start command
	private final String[] startCommand =
		{ "cmd", "/c", "start", "monopd.exe" };
	
	// monopd stop command - works for Windows XP, Vista
	private final String[] killCommand =
		{ "TASKKILL", "/IM", "monopd.exe" };
	
	// file directory for monopd
	private final File monopdDirectory = 
		new File("monopd_windows");
	
	// thread, condition variable
	private volatile Thread t;
	private final Object lock = new Object();
	
	// fail flag, used for testing
	public static volatile boolean startUpFlag = false;
	
	// constructor
	public Monopd()
	{
		builder = new ProcessBuilder( startCommand );
		builder.directory( monopdDirectory );
	}
	
	// start method
	public void start() throws Exception
	{
		t = new Thread( this );
		t.start();
	}
	
	// stop method
	public void stop()
	{
		synchronized( lock )
		{
			lock.notifyAll();
		}
	}
	
	// interrupt this thread
	public void interrupt()
	{
		t.interrupt();
	}
	
	// run method
	public void run()
	{
		synchronized( lock )
		{
			try
			{
				// start monopd
				process = builder.start();
				try
				{
					// startUpFlag is true, wait on the lock to terminate
					Monopd.startUpFlag = true;
					lock.wait();
				} 
				catch ( InterruptedException ie )
				{
					ie.printStackTrace();
				}
			}
			catch( Exception e ) // start() potentially throws null or IO
			{
				// exit run method and nullify the process
				Monopd.startUpFlag = false;
				process.destroy();
				process = null;
				e.printStackTrace();
			}
			
			// fun is over, time to kill monopd
			Monopd.startUpFlag = false;
			try
			{
				Runtime.getRuntime().exec( killCommand );
				process.destroy();
				process = null;
			}
			catch( Exception e )
			{
				System.out.print( "kill command failed\n" );
				e.printStackTrace();
			}
		}
	}

	/**
	 * @return the process
	 */
	public Process getProcess()
	{
		return process;
	}
}